<?php
/**
 * Created by PhpStorm.
 * FileName: Appointment.class.php
 * User: Administrator
 * Date: 2018/4/16
 * Time: 10:02
 */

namespace Api\Controller;


use Admin\Model\AppointmentModel;
use Admin\Model\BespeakModel;
use Admin\Model\OrganizationModel;
use Admin\Model\UserModel;
use Common\Lib\Util\LogUtil;

class AppointmentController extends ApiController {

    private $orgModel;
    private $userModel;
    private $bespeakModel;
    private $appointmentModel;

    public function __construct() {
        parent::__construct();
        $this->orgModel = new OrganizationModel();
        $this->userModel = new UserModel();
        $this->bespeakModel = new BespeakModel();
        $this->appointmentModel = new AppointmentModel();
    }

    public function getList() {
        $where = array(
            'member_id' => session('userId')
        );
        $order = 'order_time desc,create_time desc';
        $curPage = I('p',1);
        $data = $this->bespeakModel->apiList($where,$curPage,10,$order);
        $data['curPage'] = $data['curPage']+1;
        return $this->callBack("预约列表",$this->SUCCESS_CODE,$data);
    }

    public function add() {
        $data = array();
        $orgList = $this->orgModel->order('convert(name using gbk) asc')->select();
        $data['orgList'] = $orgList;
        return $this->callBack("添加预约",$this->SUCCESS_CODE,$data);
    }

    public function doAdd() {
        $data = array();
        $memberId = session('userId');
        //$userId = $_POST['user_id'];
        $orgId = $_POST['org_id'];
        $orderTime = $_POST['order_time'];
        $timeRange = $_POST['time_range'];
        $content = $_POST['content'];
        $memberName = $_POST['member_name'];
        $mobile = $_POST['mobile'];

        $appointments = $this->getAvailableAppointments($orgId,$orderTime);
        $userId = $this->getFirstUser($appointments,$timeRange);

        if (!$memberId || !$userId || !$orderTime || !$timeRange || !$memberName || !$mobile) {
            return $this->callBack("无效的参数！",$this->ERROR_CODE);
        }

        if ($this->appointmentModel->isAvailable($orgId,$userId,$orderTime,$timeRange) === false) {
            return $this->callBack("该服务人员的当前时间段不接受预约，请重新选择！",$this->ERROR_CODE);
        }

        if ($this->bespeakModel->isValid($orgId,$userId,$orderTime,$timeRange) === false) {
            return $this->callBack("该服务人员的当前时间段已被约满，请重新选择！",$this->ERROR_CODE);
        }

        $data['member_id'] = $memberId;
        $data['user_id'] = $userId;
        $data['org_id'] = $orgId;
        $data['order_time'] = $orderTime;
        $data['time_range'] = $timeRange;
        $data['content'] = $content;
        $data['member_name'] = $memberName;
        $data['mobile'] = $mobile;
        $rs = $this->bespeakModel->add($data);
        if ($rs !== false) {
            $row = $this->bespeakModel->relation(array('user','member','org'))->where(array('id' => $rs))->find();
            $templateId = C('WEIXIN_TEMPLATE_BESPEAK_HANDLE');
            $title = '发送预约通知！';
            $option = array(
                //预约事项
                'event' => array('value' => $row['content'],'color' => '#173177'),
                //预约时间
                'date' => array('value' => sprintf('%s（%s）',date('Y年m月d日',$row['order_time']),$row['time_range']),'color' => '#173177'),
                //预约编码
                'no' => array('value' => date('YmdHis',$row['create_time']),'color' => '#173177'),
                //备注
                'remark' => array('value' => '请携带相关证件。','color' => '#173177')
            );
            //预约单位
            $option['dept'] = array('value' => sprintf('%s（服务人员：%s）',$row['org']['name'],$row['user']['real_name']),'color' => '#173177');
            $options = array(
                'templateId' => $templateId,
                'bespeakId' => $rs,
                'openId' => session('openId'),
                'userType' => '普通用户',
                'data' => $option,
                'title' => $title
            );
            //发送给预约人员
            $this->sendNotice($options);

            //发送给工作人员
            $openId = $this->userModel->where(array('id' => $row['user_id']))->getField('openid');
            if ($openId) {
                //预约单位
                $option['dept'] = array('value' => sprintf('%s（预约用户：%s）',$row['org']['name'],$row['member_name']),'color' => '#173177');
                $options['openId'] = $openId;
                $options['userType'] = '工作人员';
                $options['data'] = $option;
                $this->sendNotice($options);
            }

            return $this->callBack("预约成功！",$this->SUCCESS_CODE);
        }
        return $this->callBack("预约失败！",$this->ERROR_CODE);
    }

    //根据部门和日期，查询可用的预约时间段
    public function getAvailableTimeRange() {
        $orgId = $_REQUEST['org_id'];
        $orderTime = $_REQUEST['order_time'];
        if (!$orgId || !$orderTime) {
            $this->callBack('无效的参数',$this->ERROR_CODE);
        }
        $appointments = $this->getAvailableAppointments($orgId,$orderTime);
        $availableTimeRange = array();
        foreach ($appointments as $timeRanges) {
            $availableTimeRange = array_merge($availableTimeRange,$timeRanges);
        }
        $availableTimeRange = array_unique($availableTimeRange);
        if ($availableTimeRange) {
            sort($availableTimeRange);
            $this->callBack('可用时间段列表',$this->SUCCESS_CODE,$availableTimeRange);
        } else {
            $this->callBack('没有可用的时间段，请重新选择日期',$this->ERROR_CODE);
        }
    }

    //根据部门和预约时间段，查询剩余人数
    public function getAvailableSurplusNum() {
        $orgId = $_REQUEST['org_id'];
        $orderTime = $_REQUEST['order_time'];
        $timeRange = $_REQUEST['time_range'];
        if (!$orgId || !$orderTime || !$timeRange) {
            $this->callBack('无效的参数',$this->ERROR_CODE);
        }
        $surplusNum = $this->getSurplusNum($orgId,$orderTime,$timeRange);
        $this->callBack('',$this->SUCCESS_CODE,$surplusNum);
    }

    /**
     * 获取部门剩余预约人数
     * @param $orgId
     * @param $orderTime
     * @return array
     * @param $timeRange
     */
    private function getSurplusNum($orgId,$orderTime,$timeRange) {
        $data = array();
        $total = $this->appointmentModel->getTotalNums($orgId,$orderTime);
        $reservedNums = $this->bespeakModel->getReservedNums($orgId,$orderTime,$timeRange);
        $total = $total ? $total : 0;
        $reservedNums = $reservedNums ? $reservedNums : 0;
        $data['total'] = $total;
        $data['surplus'] = ($total > $reservedNums) ? $total - $reservedNums : 0;
        return $data;

    }

    /**
     * 获取每个用户可用的预约时间段
     * @param $orgId
     * @param $orderTime
     * @return array
     */
    private function getAvailableAppointments($orgId,$orderTime) {
        $availableAppointments = array();
        $appointments = $this->appointmentModel->getAppoints($orgId,$orderTime);
        $bespeaks = $this->bespeakModel->getBespeaks($orgId,$orderTime);

        foreach ($appointments as $userId => $appointment) {
            $timeRanges = $appointment['time_range'];
            $reservedTimeRange = $bespeaks[$userId];
            if ($reservedTimeRange) {
                //统计每个时间段被预约的人数
                $reservedNums = array_count_values($reservedTimeRange);
                foreach($timeRanges as $k => $v){
                    if(in_array($v,$reservedTimeRange) && $reservedNums[$v]>=$appointment['nums']){
                        unset($timeRanges[$k]);
                    }
                }
            }
            if ($timeRanges) {
                $availableAppointments[$userId] = $timeRanges;
            }
        }
        return $availableAppointments;
    }

    //发送预约通知
    private function sendNotice($options) {
        $option = array(
            //接收者openid
            'touser' => $options['openId'],
            //模板ID
            'template_id' => $options['templateId'],
            //模板跳转链接，不填则不用跳转
            'url' => '',
            //模板数据
            'data' => $options['data']
        );
        $response = sendWenXinNotice($option);
        $result = $response['result'];
        LogUtil::info(sprintf('%s接收方用户类型：%s',$options['title'],$options['userType']));
        if (is_array($result)) {
            $result['bespeakId'] = $options['bespeakId'];
            $result['toUser'] = $options['openId'];
            $result['userType'] = $options['userType'];
            LogUtil::info($result);
        } else {
            LogUtil::info(sprintf('预约id : %s , openId : %s , 用户类型 : %s , 信息 : %s', $options['bespeakId'], $options['openId'], $options['userType'], $response['weObj']->errMsg));
        }
        return $result;
    }

    //获取预约时间段内的第一个服务用户
    private function getFirstUser($appointments,$timeRange) {
        $userId = '';
        foreach ($appointments as $key => $timeRanges) {
            if (in_array($timeRange,$timeRanges)) {
                $userId = $key;
                break;
            }
        }
        return $userId;
    }

    //取消预约
    public function cancelBespeak() {
        $id = I('id');
        if (!$id) {
            return $this->callBack('无效的参数!',$this->ERROR_CODE);
        }
        $row = $this->bespeakModel->where(array('id' => $id))->find();
        $orderDate = date('Y-m-d H:i:s',$row['order_time']);
        $timeRange = $row['time_range'];
        $rangeStart = sprintf('%s:00',substr($timeRange,0,5));
        $rangeEnd = sprintf('%s:00',substr($timeRange,8));
        $orderStart = strtotime(str_replace('00:00:00',$rangeStart,$orderDate));
        $orderEnd = strtotime(str_replace('00:00:00',$rangeEnd,$orderDate));

        if ($orderEnd < time()) {
            return $this->callBack('预约已过期，无法取消!',$this->ERROR_CODE);
        } else {
            $minute = floor(($orderStart - time())/60);
            if ($minute < 30) {
                return $this->callBack('预约开始前的30分钟，无法取消!',$this->ERROR_CODE);
            }
        }

        $rs = $this->bespeakModel->where(array('id' => $id))->save(array('status' => 0));
        if ($rs !== false) {
            $row = $this->bespeakModel->relation(array('member'))->where(array('id' => $id))->find();
            $templateId = C('WEIXIN_TEMPLATE_BESPEAK_CANCEL');
            $title = '预约取消通知！';
            $option = array(
                'first' => array('value' =>'预约已取消','color' => '#ff0000'),
                //预约号
                'keyword1' => array('value' => date('YmdHis',$row['create_time']),'color' => '#173177'),
                //预约时间
                'keyword2' => array('value' => sprintf('%s（%s）',date('Y年m月d日',$row['order_time']),$row['time_range']),'color' => '#173177'),
                //备注
                'remark' => array('value' => sprintf('%s %s的预约已成功取消，操作人：%s',date('Y年m月d日',$row['order_time']),$row['time_range'],$row['member']['real_name']),'color' => '#ff0000')
            );
            //预约单位
            $options = array(
                'templateId' => $templateId,
                'bespeakId' => $id,
                'openId' => session('openId'),
                'userType' => '普通用户',
                'data' => $option,
                'title' => $title
            );
            //发送给预约人员
            $this->sendNotice($options);

            //发送给工作人员
            $openId = $this->userModel->where(array('id' => $row['user_id']))->getField('openid');
            if ($openId) {
                //预约单位
                $options['openId'] = $openId;
                $options['userType'] = '工作人员';
                $this->sendNotice($options);
            }
            return $this->callBack('预约信息取消成功！',$this->SUCCESS_CODE);
        }
        return $this->callBack('预约信息取消失败！',$this->ERROR_CODE);
    }

}